﻿using MaterialManagement.API.Application.Command.ERP;
using MaterialManagement.Domain.ERP;
using MaterialManagement.ErrorCode;
using MaterialManagement.Infrastructure.Implement;
using MaterialManagement.Infrastructure.Interface;
using MediatR;

namespace MaterialManagement.API.Application.Handler.ERP
{
    public class UpdStateMaterialRequisitionHandler : IRequestHandler<UpdStateMaterialRequisitionCommand, APIResult<int>>
    {
        private readonly DatabaseContext database;

        public UpdStateMaterialRequisitionHandler(DatabaseContext database)
        {
            this.database = database;
        }
        public async Task<APIResult<int>> Handle(UpdStateMaterialRequisitionCommand request, CancellationToken cancellationToken)
        {
            APIResult<int> result = new APIResult<int>();
            try
            {
                await database.SqlSugar.Ado.BeginTranAsync();

                var res = await database.SqlSugar.Queryable<OutboundRecordModel>()
                    .FirstAsync(x => x.OutboundId == request.OutboundId);

                if (res == null)
                {
                    await database.SqlSugar.RollbackTranAsync();
                    result.Code = APIEnum.Fail;
                    result.Message = "找不到该领料单";
                    return result;
                }

                res.PickState = true;
                await database.SqlSugar.Updateable(res)
                    .UpdateColumns(r => new { r.PickState })
                    .ExecuteCommandAsync();

                var pickings = await database.SqlSugar.Queryable<PickingModel>()
                    .Where(x => x.PickFormCode == res.PickFormCode)
                    .ToListAsync();

                if (pickings == null || pickings.Count == 0)
                {
                    await database.SqlSugar.CommitTranAsync();
                    result.Code = APIEnum.Ok;
                    result.Message = "出库成功";
                    result.Data = 0;
                    return result;
                }

                var materialCodes = pickings.Select(p => p.MaterialCode).Distinct().ToList();

                var materials = await database.SqlSugar.Queryable<MaterialInfoModel>()
                    .Where(m => materialCodes.Contains(m.MaterialCode))
                    .ToListAsync();

                var missingCodes = materialCodes.Except(materials.Select(m => m.MaterialCode)).ToList();
                if (missingCodes.Count > 0)
                {
                    await database.SqlSugar.RollbackTranAsync();
                    result.Code = APIEnum.Fail;
                    result.Message = "该领料单中包含未拥有的物料";
                    return result;
                }

                foreach (var item in pickings)
                {
                    var material = materials.First(m => m.MaterialCode == item.MaterialCode);
                    material.CurrentInventory = material.CurrentInventory - item.PickingQuantity;
                    await database.SqlSugar.Updateable(material)
                        .UpdateColumns(m => new { m.CurrentInventory })
                        .ExecuteCommandAsync();
                }

                await database.SqlSugar.CommitTranAsync();
                result.Code = APIEnum.Ok;
                result.Message = "出库成功";
                result.Data = 1;
            }
            catch
            {
                await database.SqlSugar.RollbackTranAsync(); // 异常回滚
                throw;
            }
            return result;
        }
    }
}
